package cn.edu.imnu.controller.common;

import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectListing;
import common.model.DataBootstrapTable;
import common.model.ResponseModelBootstrapTable;
import common.model.ResponseModelJqGrid;
import common.util.AliyunOssUtil;
import common.util.JSONHandler;
import common.util.StringProcessor;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;


@Controller
@RequestMapping("/common/upload")
public class FileUpload {

	private static Logger logger = LoggerFactory.getLogger(FileUpload.class);

	// private static String upDiv = "/wordImages\\";
	private static String upDiv = "/Users/ranhongmin/Work/testImages/";

	/**
	 * 公共文件上传接口（客户端使用“uploadify”）。 参数：savePath 文件在服务器保存的相对路径；
	 *
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "up.json", method = RequestMethod.POST)
	public void upOne(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String[]> parameterMap = request.getParameterMap(); // 通过
		// “uploadify”上传的数据格式为Map<String,
		// String[]>。
		Map<String, String> map = new HashMap<String, String>();
		// 客户端传入的参数转换，Map<String, String[]> -- Map<String, String>，
		// 去数组中第一个元素，同时要求客户端不要使用相同的Key传入数据。
		for (Map.Entry<String, String[]> e : parameterMap.entrySet()) {
			String key = e.getKey();
			String[] value = e.getValue();
			if (value.length > 0) {
				map.put(key, value[0]);
			}
		}

		if (StringProcessor.isNotEmptyStr(map.get("savePath"))) {
			upDiv = map.get("savePath");
		}

		ResponseModelJqGrid model = new ResponseModelJqGrid();
		List<Map<String, String>> fileInfo = null;
		try {
			fileInfo = UploadProcessing.uploder(request, upDiv);
			model.success();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("控制：处理上传文件发生异常。");
			model.error("控制：处理上传文件发生异常。");
		}

		try {
			// 设置HTTP响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("application/json; charset=utf-8");
			if (fileInfo != null && fileInfo.size() > 0) {
				model.setList(fileInfo);
			}
			logger.info("控制：" + fileInfo);
			logger.info("数据：" + map);

			response.getWriter().write(JSONHandler.toJSON(model));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "upPic.json", method = RequestMethod.POST)
	public void upPic(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String[]> parameterMap = request.getParameterMap(); // 通过
		// “uploadify”上传的数据格式为Map<String,
		// String[]>。
		Map<String, String> map = new HashMap<String, String>();
		// 客户端传入的参数转换，Map<String, String[]> -- Map<String, String>，
		// 去数组中第一个元素，同时要求客户端不要使用相同的Key传入数据。
		for (Map.Entry<String, String[]> e : parameterMap.entrySet()) {
			String key = e.getKey();
			String[] value = e.getValue();
			if (value.length > 0) {
				map.put(key, value[0]);
			}
		}

		// if (StringProcessor.isNotEmptyStr(map.get("savePath"))) {
		// 	upDiv = map.get("savePath");
		// }

		ResponseModelJqGrid model = new ResponseModelJqGrid();
		List<Map<String, String>> fileInfo = null;
		try {
			fileInfo = UploadProcessing.uploderPic(request, upDiv);
			model.success();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("控制：处理上传文件发生异常。");
			model.error("控制：处理上传文件发生异常。");
		}

		try {
			// 设置HTTP响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("application/json; charset=utf-8");
			if (fileInfo != null && fileInfo.size() > 0) {
				model.setList(fileInfo);
			}
			response.getWriter().write(JSONHandler.toJSON(model));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("headup.json")
	@ResponseBody
	public JSONObject headPicker() {
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		JSONObject jsonObject = AliyunOssUtil.getOSSToken();
		ossUtil.destory();
		return jsonObject;

	}

	/**
	 * 百度富文本框涂鸦上传
	 *
	 * @param response
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value = "scrawlUpload", method = RequestMethod.POST)
	public Map<String, Object> scrawlUpload(HttpServletResponse response,
											HttpServletRequest request) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		String filetype = request.getParameter("filetype");
		// System.out.println("filetype:" + filetype);
		//Base64编码过的图片数据信息，对字节数组字符串进行Base64解码
		String upfile = request.getParameter("upfile");
		// System.out.println("upfile:" + upfile);
		String basePath = "";

		//获得files目录的绝对路径
		String path = request.getSession().getServletContext().getRealPath("files");
		String targetFileName = UUID.randomUUID().toString() + ".png";
		File targetFile = new File(path, targetFileName);
		String url = null;
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}


		// 使用BASE64对图片文件数据进行解码操作
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			// 通过Base64解密，将图片数据解密成字节数组
			byte[] bytes = decoder.decodeBuffer(upfile);
			// 构造字节数组输入流
			ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
			// 读取输入流的数据
			BufferedImage bi = ImageIO.read(bais);
			// 将数据信息写进图片文件中
			ImageIO.write(bi, "png", targetFile);
			// 不管输出什么格式图片，此处不需改动


			List<Map<String, String>> fileInfo = null;
			try {
				fileInfo = UploadProcessing.uploderPic(request, upDiv);
				// AliyunOssUtil util = new AliyunOssUtil();
				// util.uploadFile(targetFile, "UEDITORTEST" + targetFileName);
				// url = util.getRealUrl("/UEDITORTEST" + targetFileName);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("控制：处理上传文件发生异常。");
			}
			assert fileInfo != null;
			url = fileInfo.get(0).get("uri");

			params.put("state", "SUCCESS");
			params.put("url", url);
			params.put("title", targetFileName);
			params.put("original", targetFileName);
			bais.close();
		} catch (IOException e) {
			e.printStackTrace();
		}


		return params;
	}


	/**
	 * 百度富文本框上传
	 *
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping("UeditorUPFIle.json")
	@ResponseBody
	public Map<String, Object> UeditorUPFIle(@RequestParam(value = "upfile", required = false) MultipartFile file, HttpServletRequest request) {
		Map<String, String[]> parameterMap = request.getParameterMap(); // 通过
		// “uploadify”上传的数据格式为Map<String,
		// String[]>。
		Map<String, String> map = new HashMap<String, String>();
		// 客户端传入的参数转换，Map<String, String[]> -- Map<String, String>，
		// 去数组中第一个元素，同时要求客户端不要使用相同的Key传入数据。
		for (Map.Entry<String, String[]> e : parameterMap.entrySet()) {
			String key = e.getKey();
			String[] value = e.getValue();
			if (value.length > 0) {
				map.put(key, value[0]);
			}
		}

		// if (StringProcessor.isNotEmptyStr(map.get("savePath"))) {
		// 	upDiv = map.get("savePath");
		// }

		ResponseModelJqGrid model = new ResponseModelJqGrid();
		List<Map<String, String>> fileInfo = null;
		try {
			fileInfo = UploadProcessing.uploderPic(request, upDiv);
			model.success();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("控制：处理上传文件发生异常。");
			model.error("控制：处理上传文件发生异常。");
		}

		// try {
		// 	设置HTTP响应头
			// response.setHeader("Pragma", "No-cache");
			// response.setHeader("Cache-Control", "No-cache");
			// response.setDateHeader("Expires", 0);
			// response.setContentType("application/json; charset=utf-8");
			// if (fileInfo != null && fileInfo.size() > 0) {
			// 	model.setList(fileInfo);
			// }
			// response.getWriter().write(JSONHandler.toJSON(model));
		// } catch (IOException e) {
		// 	e.printStackTrace();
		// }

		// 图片和文件的返回要求
		// original: "1.png"
		// size: "86846"
		// state: "SUCCESS"
		// title: "1484710315158045904.png"
		// type: ".png"
		// url: "/ueditor/jsp/upload/image/20170118/1484710315158045904.png"

		// model.setList(fileInfo);

		Map<String, Object> result = new HashMap<String, Object>();
		result.put("state", "SUCCESS");// UEDITOR的规则:不为SUCCESS则显示state的内容
		// result.put("url", "/files/" + targetFileName);
		result.put("url", ""+fileInfo.get(0).get("uri"));
		// result.put("url", "/UEDITORTEST" + targetFileName);
		result.put("title", file.getOriginalFilename());
		result.put("original", file.getOriginalFilename());
		result.put("size", file.getSize());
		result.put("type",".png");
		return result;
	}


	@RequestMapping("upFile.json")
	@ResponseBody
	public void upFile(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String[]> parameterMap = request.getParameterMap(); // 通过
		// “uploadify”上传的数据格式为Map<String,
		// String[]>。
		Map<String, String> map = new HashMap<String, String>();
		// 客户端传入的参数转换，Map<String, String[]> -- Map<String, String>，
		// 去数组中第一个元素，同时要求客户端不要使用相同的Key传入数据。
		for (Map.Entry<String, String[]> e : parameterMap.entrySet()) {
			String key = e.getKey();
			String[] value = e.getValue();
			if (value.length > 0) {
				map.put(key, value[0]);
			}
		}

		if (StringProcessor.isNotEmptyStr(map.get("savePath"))) {
			upDiv = map.get("savePath");
		}

		ResponseModelJqGrid model = new ResponseModelJqGrid();
		List<Map<String, String>> fileInfo = null;
		try {

			List<Map<String, String>> result = new ArrayList<Map<String, String>>();
			String webappRoot = System.getProperty("webapp.root");
			if (webappRoot == null) {
				webappRoot = request.getSession().getServletContext().getRealPath("/");
			}

			String filePath = webappRoot + upDiv.replace("\\", System.getProperty("file.separator"));
			File fileOnServer = new File(filePath);

			fileInfo = UploadProcessing.uploadFile(request, upDiv);
			model.setList(fileInfo);
			model.success();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("控制：处理上传文件发生异常。");
			model.error("控制：处理上传文件发生异常。");
		}

		try {
			// 设置HTTP响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("application/json; charset=utf-8");
			// if (fileInfo != null && fileInfo.size() > 0) {
			// 	model.setList(fileInfo);
			// }
			response.getWriter().write(JSONHandler.toJSON(model));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


	/**
	 * 获取 object
	 *
	 * @param prefix 前缀
	 * @return
	 */
	@RequestMapping("getAllOssObject.json")
	@ResponseBody
	public ResponseModelBootstrapTable getAllObjectList(String prefix) {
		ResponseModelBootstrapTable modelBootstrapTable = new ResponseModelBootstrapTable();
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		ObjectListing list = ossUtil.getAllObject(prefix);
		modelBootstrapTable.setObject(list);
		ossUtil.destory();
		return modelBootstrapTable;
	}

	/**
	 * 通过分页获取
	 *
	 * @param dbt       分页
	 * @param nextKey   起始key
	 * @param keyPrefix 前缀
	 * @return
	 */
	@RequestMapping("getOssObjectPage.json")
	@ResponseBody
	public ResponseModelBootstrapTable pageObjectTest(DataBootstrapTable dbt, String nextKey, String keyPrefix) {
		ResponseModelBootstrapTable modelBootstrapTable;
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		int limit;
		if (dbt.getLimit() != 10) {

			limit = dbt.getLimit();
		} else {
			limit = 0;
		}
		modelBootstrapTable = ossUtil.getAllObjectByPageSize(limit, nextKey, keyPrefix);
		ossUtil.destory();
		List<String> strings = (List<String>) modelBootstrapTable.get("obj");

		List maps = new ArrayList<>();
		for (String str :
				strings) {
			Map<String, String> map = new HashMap<>();
			map.put("key", str);
			maps.add(map);
		}

		List<?> objects = modelBootstrapTable.getRows();
		maps.addAll(objects);
		// page.setTotalLine(sysUserMapper.selectCountByExample(example));
		// model.bing(sysuser, page.getTotalLine(), page.getTotalPage());

		modelBootstrapTable.bing(maps, maps.size(), 2);
		return modelBootstrapTable;
	}

	/**
	 * 删除object
	 *
	 * @param key key
	 * @return
	 */
	@RequestMapping("deleteObject.json")
	@ResponseBody
	public ResponseModelBootstrapTable deleteObject(String key) {
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		ossUtil.deleteObject(key);
		return new ResponseModelBootstrapTable().success();
	}

	/**
	 * 创建一个文件夹（？
	 *
	 * @param str
	 * @return
	 */
	@RequestMapping("mkdir.json")
	@ResponseBody
	public ResponseModelBootstrapTable mkdir(String str) {
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		ossUtil.makeDir(str);
		ossUtil.destory();
		return new ResponseModelBootstrapTable().success();
	}

	@RequestMapping("downloadFile.json")
	@ResponseBody
	public ResponseEntity<byte[]> download(HttpServletRequest request,
										   @RequestParam("filename") String filename) throws Exception {
		//下载文件路径
		File file = null;
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		OSSObject object = ossUtil.downloadFile(filename);
		InputStream df = object.getObjectContent();
		//inputStream ->file
		OutputStream os = new FileOutputStream(file);
		int bytesRead = 0;
		byte[] buffer = new byte[8192];
		while ((bytesRead = df.read(buffer, 0, 8192)) != -1) {
			os.write(buffer, 0, bytesRead);
		}
		os.close();
		df.close();


		HttpHeaders headers = new HttpHeaders();
		//下载显示的文件名，解决中文名称乱码问题
		String downloadFielName = new String(filename.getBytes("UTF-8"), "iso-8859-1");
		//通知浏览器以attachment（下载方式）打开图片
		headers.setContentDispositionFormData("attachment", downloadFielName);
		//application/octet-stream ： 二进制流数据（最常见的文件下载）。
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.CREATED);
	}

	/**
	 * 获取文件url提供下载
	 *
	 * @param key key
	 * @return
	 */
	@RequestMapping("downloadByUrl.json")
	@ResponseBody
	public ResponseModelBootstrapTable downloadByUrl(String key) {
		ResponseModelBootstrapTable modelBootstrapTable = new ResponseModelBootstrapTable();
		AliyunOssUtil ossUtil = new AliyunOssUtil();
		modelBootstrapTable.setObject(ossUtil.getUrl(key));
		ossUtil.destory();
		return modelBootstrapTable;

	}

	/**
	 * 断点分片
	 *
	 * @param request
	 * @param response
	 */
	@RequestMapping("uploadFileAsMultipart.json")
	@ResponseBody
	public void uploadFileAsMultipart(HttpServletRequest request, HttpServletResponse response) {
		Map<String, String[]> parameterMap = request.getParameterMap(); // 通过
		// “uploadify”上传的数据格式为Map<String,
		// String[]>。
		Map<String, String> map = new HashMap<String, String>();
		// 客户端传入的参数转换，Map<String, String[]> -- Map<String, String>，
		// 去数组中第一个元素，同时要求客户端不要使用相同的Key传入数据。
		for (Map.Entry<String, String[]> e : parameterMap.entrySet()) {
			String key = e.getKey();
			String[] value = e.getValue();
			if (value.length > 0) {
				map.put(key, value[0]);
			}
		}

		if (StringProcessor.isNotEmptyStr(map.get("savePath"))) {
			upDiv = map.get("savePath");
		}

		ResponseModelJqGrid model = new ResponseModelJqGrid();
		List<Map<String, String>> fileInfo = null;
		try {

			List<Map<String, String>> result = new ArrayList<Map<String, String>>();
			String webappRoot = System.getProperty("webapp.root");
			if (webappRoot == null) {
				webappRoot = request.getSession().getServletContext().getRealPath("/");
			}

			String filePath = webappRoot + upDiv.replace("\\", System.getProperty("file.separator"));
			File fileOnServer = new File(filePath);

			try {
				fileInfo = UploadProcessing.uploadFileMultipart(request, upDiv);
			} catch (Throwable throwable) {
				throwable.printStackTrace();
			}
			model.setList(fileInfo);
			model.success();
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("控制：处理上传文件发生异常。");
			model.error("控制：处理上传文件发生异常。");
		}

		try {
			// 设置HTTP响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("application/json; charset=utf-8");
			// if (fileInfo != null && fileInfo.size() > 0) {
			// 	model.setList(fileInfo);
			// }
			response.getWriter().write(JSONHandler.toJSON(model));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
